001 /*
002 * Copyright 2004 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.metro.info;
020
021 import java.io.Serializable;
022
023 import java.util.Properties;
024
025 /**
026 * This is the Abstract class for all feature feature descriptors.
027 *
028 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
029 * @version 1.0.0
030 */
031 public abstract class Descriptor
032 implements Serializable
033 {
034 /**
035 * Serial version identifier.
036 */
037 static final long serialVersionUID = 1L;
038
039 private static final String[] EMPTY_SET = new String[0];
040
041 /**
042 * The arbitrary set of attributes associated with Component.
043 */
044 private final Properties m_attributes;
045
046 /**
047 * Creation of an abstract descriptor.
048 * @param attributes the set of attributes to assign to the descriptor
049 */
050 protected Descriptor( final Properties attributes )
051 {
052 m_attributes = attributes;
053 }
054
055 /**
056 * Return the attribute for specified key.
057 *
058 * @param key the attribute key to resolve
059 * @return the attribute for specified key.
060 */
061 public String getAttribute( final String key )
062 {
063 if ( null == m_attributes )
064 {
065 return null;
066 }
067 else
068 {
069 return m_attributes.getProperty( key );
070 }
071 }
072
073 /**
074 * Return the attribute for specified key.
075 *
076 * @param key the attribute key to resolve
077 * @param defaultValue the default value to use if the value is not defined
078 * @return the attribute for specified key.
079 */
080 public String getAttribute( final String key, final String defaultValue )
081 {
082 if ( null == m_attributes )
083 {
084 return defaultValue;
085 }
086 else
087 {
088 return m_attributes.getProperty( key, defaultValue );
089 }
090 }
091
092 /**
093 * Returns the set of attribute names available under this descriptor.
094 *
095 * @return an array of the properties names held by the descriptor.
096 */
097 public String[] getAttributeNames()
098 {
099 if ( null == m_attributes )
100 {
101 return EMPTY_SET;
102 }
103 else
104 {
105 return (String[]) m_attributes.keySet().toArray( EMPTY_SET );
106 }
107 }
108
109 /**
110 * Compare this object with another for equality.
111 * @param other the object to compare this object with
112 * @return TRUE if the supplied object equivalent
113 */
114 public boolean equals( Object other )
115 {
116 if ( other instanceof Descriptor )
117 {
118 Descriptor descriptor = (Descriptor) other;
119 return equals( m_attributes, descriptor.m_attributes );
120 }
121 else
122 {
123 return false;
124 }
125 }
126
127 /**
128 * Return the hashcode for the object.
129 * @return the hashcode value
130 */
131 public int hashCode()
132 {
133 if( m_attributes != null )
134 {
135 return m_attributes.hashCode();
136 }
137 else
138 {
139 return 132482349;
140 }
141 }
142
143 /**
144 * Returns the property set.
145 *
146 * @return the property set.
147 */
148 public Properties getProperties()
149 {
150 return m_attributes;
151 }
152
153 /**
154 * Utility to hash an array.
155 * @param array the array
156 * @return the hash value
157 */
158 int hashArray( Object[] array )
159 {
160 if( null == array )
161 {
162 return 0;
163 }
164 int hash = 0;
165 for( int i=0; i<array.length; i++ )
166 {
167 Object object = array[i];
168 hash ^= hashValue( object );
169 }
170 return hash;
171 }
172
173 /**
174 * Utility to hash an object.
175 * @param value the object
176 * @return the hash value
177 */
178 int hashValue( Object value )
179 {
180 if( null == value )
181 {
182 return 0;
183 }
184 else if( value instanceof Object[] )
185 {
186 return hashArray( (Object[]) value );
187 }
188 else
189 {
190 return value.hashCode();
191 }
192 }
193
194 /**
195 * Utility to compare two object for equality.
196 * @param a the first object
197 * @param b the second object
198 * @return true if the objects are equal
199 */
200 boolean equals( Object a, Object b )
201 {
202 if( null == a )
203 {
204 return ( null == b );
205 }
206 else
207 {
208 return a.equals( b );
209 }
210 }
211 }